package educrypt.filter;

import java.util.*;
import java.util.Map.Entry;

public class Equivalences implements Iterable<Entry<Character, Character>> {
	public static final char NULLSYMBOL = ' ';

	private SortedMap<Character, Character> equivalences;

	public Equivalences() {
		equivalences = new TreeMap<Character, Character>();
	}

	public Equivalences(List<Character> symbols,
			List<Character> equivalentSymbols) {
		equivalences = new TreeMap<Character, Character>();

		assert symbols.size() == equivalentSymbols.size();

		for (int i = 0; i < symbols.size(); i++) {
			equivalences.put(symbols.get(i), equivalentSymbols.get(i));
		}
	}

	public void addNewSymbol(char symbol) {
		if (equivalences.get(symbol) == null) {
			equivalences.put(symbol, Equivalences.NULLSYMBOL);
		}
	}

	public void addNewSymbols(List<Character> symbols) {
		for (char symbol : symbols) {
			this.addNewSymbol(symbol);
		}
	}

	public void addEquivalence(char symbol, char equivalence) {
		equivalences.put(symbol, equivalence);
	}

	public char getEquivalentSymbol(char symbol) {
		boolean symbolUpperCase = Character.isUpperCase(symbol);
		if (symbolUpperCase) {
			symbol = Character.toLowerCase(symbol);
		}

		Character equivalence = equivalences.get(symbol);
		if (equivalence == null || equivalence == Equivalences.NULLSYMBOL) {
			equivalence = symbolUpperCase ? Character.toUpperCase(equivalence)
					: equivalence;
		}
		return equivalence;
	}

	public List<Integer> getSymbolsPositions(List<Character> symbols) {
		List<Character> tmp = new ArrayList<Character>(equivalences.keySet());
		List<Integer> positions = new ArrayList<Integer>();
		for (char symbol : symbols) {
			int symbolPos = tmp.indexOf(symbol);
			if (symbolPos >= 0) {
				positions.add(symbolPos);
			}
		}
		return positions;
	}

	public List<Character> getAllSymbols() {
		List<Character> symbols = new ArrayList<Character>(
				equivalences.keySet());
		return symbols;
	}

	public List<Character> getAllEquivalentSymbols() {
		List<Character> equivalentSymbols = new ArrayList<Character>(
				equivalences.values());
		return equivalentSymbols;
	}

	@Override
	public Iterator<Entry<Character, Character>> iterator() {
		return equivalences.entrySet().iterator();
	}
}
